use serde::{Serialize, Deserialize};
use super::log_level_visit::LogLevelVisitor;

#[derive(Debug, Clone, Copy)]
pub enum LogLevel {
  Dev,
  Info,
  Error
}

impl LogLevel {
  pub fn to_string(&self) -> String {
    match self {
      LogLevel::Dev => "dev".to_string(),
      LogLevel::Info => "info".to_string(),
      LogLevel::Error => "error".to_string(),
    }
  }

  pub fn to_u8(&self) -> u8 {
    match self {
      LogLevel::Dev => 0,
      LogLevel::Info => 1,
      LogLevel::Error => 2,
    }
  }

  pub fn from_str(s: &str) -> Result<LogLevel, String> {
    match s {
      "dev" => Ok(LogLevel::Dev),
      "Dev" => Ok(LogLevel::Dev),
      "development" => Ok(LogLevel::Dev),
      "info" => Ok(LogLevel::Info),
      "information" => Ok(LogLevel::Info),
      "error" => Ok(LogLevel::Error),
      "err" => Ok(LogLevel::Error),
      _ => Err(format!("invalid LogLevel: {s}")),
    }
  }
}

impl Serialize for LogLevel {
  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
    serializer.serialize_str(self.to_string().as_str())
  }
}

impl<'de> Deserialize<'de> for LogLevel {
  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
    deserializer.deserialize_str(LogLevelVisitor)
  }
}
